#include "database.h"

#define MAX_EVENT 50

LOGIN_INFO Client_Addr[20];
int client_count = 0;

LOGIN_INFO Merchant_Addr[10];
int merchant_count = 0;

LOGIN_INFO Rider_Addr[20];
int rider_count = 0;

void work(int sID, MSG msg)
{
    if (msg.identity == client)
    {
        if (msg.type == Register)
        {
            char table_name[] = "clientRegister";
            RGU *rgu = (RGU *)msg.buf;
            insert_sql(rgu, table_name);
        }
        else if (msg.type == Login)
        {
            char table_name[] = "clientRegister";
            RGU *pRgu = (RGU *)msg.buf;
            QUREY_RST pQR;

            querySql(&pQR, pRgu, table_name);

            // 如果结果的行数是>0的，说明数据库中有记录，那么登陆成功
            if (pQR.row > 0)
            {
                // 因为登录成功了，所以把消息类型改为ok，再发回去
                msg.type = ok;
                // 把登录成功的用户名和地址保存起来
                strcpy(Client_Addr[client_count].name, pRgu->name);
                Client_Addr[client_count].fd = sID; // 登录成功后记住用户的套接字
                Client_Addr[client_count].bo = false;
                client_count++;
            }
            // 把消息发回客户端，告诉它登录成功了
            int ret = send(sID, &msg, sizeof(msg), 0);
            if (ret == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == ViewMerchant)
        {
            QUREY_RST pQR;
            char table_name[] = "merchantRegister";

            int ret = showMerchant_Sql(&pQR, table_name);
            if (1 == ret)
            {
                msg.type = ok;
                memcpy(msg.buf, &pQR, sizeof(QUREY_RST)); // 发送元数据
            }

            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }

            // 逐条发送数据
            for (int i = 1; i <= pQR.row; i++)
            {

                strcpy(msg.buf, pQR.pzResult[i * pQR.col]);

                // 发送数据
                send(sID, &msg, sizeof(msg), 0);
            }
        }

        else if (msg.type == SelectMerchant)
        {
            QUREY_RST pQR;
            COMMODITY com;
            MENU *pRgu = (MENU *)msg.buf;
            char table_name[] = "Menu";

            int ret = show_Sql(&pQR, pRgu, table_name);
            if (1 == ret)
            {
                msg.type = ok;
                memcpy(msg.buf, &pQR, sizeof(QUREY_RST)); // 发送元数据
            }

            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }

            // 逐条发送数据
            for (int i = 1; i <= pQR.row; i++)
            {
                if (pQR.col >= 3) // 确保至少有3列
                {
                    // 将数据填充到 COMMODITY 结构体中
                    strcpy(com.dishName, pQR.pzResult[i * pQR.col + 2]); // Dishname
                    com.price = atof(pQR.pzResult[i * pQR.col + 3]);     // Price 转换为 double
                    com.sales = atoi(pQR.pzResult[i * pQR.col + 4]);     // Sales 转换为 int

                    // 将 COMMODITY 结构体数据复制到 msg.buf 中
                    memcpy(msg.buf, &com, sizeof(COMMODITY));

                    // 发送数据
                    send(sID, &msg, sizeof(msg), 0);
                }
            }
        }
        else if (msg.type == OrderMeals)
        {
            double price;
            COMMODITY com;
            QUREY_RST pQR;
            char temp[50];
            MENU *pRgu = (MENU *)msg.buf;
            char table_name[] = "Menu";
            char table_name02[] = "PendingOrder";
            char table_name03[] = "clientRegister";
            char table_name04[] = "HistoryOrders";

            strcpy(temp, pRgu->shoreID);

            int ret = order_Sql(pRgu, table_name, &price);
            if (1 == ret)
            {
                msg.type = ok;
                sprintf(msg.buf, "%.2f", price);
            }
            pRgu->Price = price;
            strcpy(pRgu->shoreID, temp);

            if (1 == findClient_Sql(&pQR, pRgu, table_name03))
            {
                printf("订单数据填写完毕！\n");
            }
            else
                printf("订单数据填写失败\n");

            if (1 == CurOrder_sql(pRgu, table_name02, table_name04))
            {
                printf("订单添加成功\n");
            }
            else
                printf("订单添加失败\n");

            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == ViewOrderStates)
        {
            QUREY_RST pQR;
            MENU pRgu;
            char table_name[] = "ClientOrders";

            int ret = FindClientOrder_Sql03(&pQR, table_name, msg.buf);
            if (1 == ret)
            {
                msg.type = ok;
                memcpy(msg.buf, &pQR, sizeof(QUREY_RST)); // 发送元数据
            }
            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }
sp
            // 逐条发送数据
            for (int i = 1; i <= pQR.row; i++)
            {
                if (pQR.col >= 7) // 确保至少有7列
                {
                    // 将数据填充到 COMMODITY 结构体中
                    pRgu.orderID = atoi(pQR.pzResult[i * pQR.col]);
                    strcpy(pRgu.shoreID, pQR.pzResult[i * pQR.col + 1]);
                    strcpy(pRgu.dishName, pQR.pzResult[i * pQR.col + 2]);
                    pRgu.Sales = atoi(pQR.pzResult[i * pQR.col + 3]);
                    pRgu.Price = atof(pQR.pzResult[i * pQR.col + 4]); // Price 转换为 double
                    strcpy(pRgu.OrderState, pQR.pzResult[i * pQR.col + 5]);
                    strcpy(pRgu.Time, pQR.pzResult[i * pQR.col + 6]);

                    // 将 COMMODITY 结构体数据复制到 msg.buf 中
                    memcpy(msg.buf, &pRgu, sizeof(MENU));

                    // 发送数据
                    send(sID, &msg, sizeof(msg), 0);
                }
            }
        }
        else if (msg.type == UserOpensChat)
        {
            for (int i = 0; i < client_count; i++)
            {
                if (0 == (strcmp(Client_Addr[i].name, msg.buf)))
                {
                    Client_Addr[i].bo = true;
                    break;
                }
            }
        }

        else if (msg.type == UserCloseChat)
        {
            for (int i = 0; i < client_count; i++)
            {
                if (0 == (strcmp(Client_Addr[i].name, msg.buf)))
                {
                    Client_Addr[i].bo = false;
                    break;
                }
            }
        }

        else if (msg.type == FindSelfChats)
        {
            QUREY_RST pQR;
            SINGLE_CHAT *sc = (SINGLE_CHAT *)msg.buf;
            char table_name[] = "ChatRecords";

            if (-1 == (FindSelfChats_Sql(&pQR, table_name, sc->selfName)))
            {
                printf("聊天记录查找失败\n");
            }

            memcpy(msg.buf, &pQR, sizeof(QUREY_RST));
            if(-1==send(sID, &msg, sizeof(msg), 0))
            {
                perror("发送数据失败!\n");
            }

            if (pQR.row > 0)
            {

                // 逐条发送数据
                for (int i = 1; i <= pQR.row; i++)
                {
                    if (pQR.col >= 3) // 确保至少有3列
                    {
                        strcpy(sc->destName, pQR.pzResult[i * pQR.col]);
                        strcpy(sc->text, pQR.pzResult[i * pQR.col + 1]);
                        strcpy(sc->time, pQR.pzResult[i * pQR.col + 2]);

                        memcpy(msg.buf, sc, sizeof(SINGLE_CHAT));
                        // 发送数据
                        send(sID, &msg, sizeof(msg), 0);
                    }
                }

                if (-1 == DeleteSelfChats_Sql(table_name, sc->selfName))
                {
                    printf("删除记录失败\n");
                }
            }
        }

        else if (msg.type == WithMerchantPrivateChat)
        {
            SINGLE_CHAT *sc = (SINGLE_CHAT *)msg.buf;
            char table_name[] = "ChatRecords";
            bool is_find = false;

            for (int i = 0; i < merchant_count; i++)
            {
                if (strcmp(sc->destName, Merchant_Addr[i].name) == 0)
                {
                    if (true == Merchant_Addr[i].bo)
                    {
                        int ret_sent = send(Merchant_Addr[i].fd, &msg, sizeof(msg), 0);
                        if (ret_sent == -1)
                        {
                            printf("发送数据出错了\n");
                        }
                        is_find = true;
                        break;
                    }
                    else
                    {
                        if (-1 == (insertChatRecords_sql(sc, table_name)))
                        {
                            printf("聊天记录插入失败\n");
                        }
                        is_find = true;
                    }
                }
            }
            if (!is_find)
            {
                if (-1 == (insertChatRecords_sql(sc, table_name)))
                {
                    printf("聊天记录插入失败\n");
                }
            }
        }
    }

    else if (msg.identity == merchant)
    {

        if (msg.type == Register)
        {
            char table_name[] = "merchantRegister";
            RGU *rgu = (RGU *)msg.buf;
            insert_sql(rgu, table_name);
        }
        else if (msg.type == Login)
        {
            char table_name[] = "merchantRegister";
            RGU *pRgu = (RGU *)msg.buf;
            QUREY_RST pQR;

            querySql(&pQR, pRgu, table_name);

            // 如果结果的行数是>0的，说明数据库中有记录，那么登陆成功
            if (pQR.row > 0)
            {
                // 因为登录成功了，所以把消息类型改为ok，再发回去
                msg.type = ok;
                // 把登录成功的用户名和地址保存起来
                strcpy(Merchant_Addr[merchant_count].name, pRgu->name);
                Merchant_Addr[merchant_count].fd = sID; // 登录成功后记住用户的套接字
                Merchant_Addr[merchant_count].bo = false;
                merchant_count++;
            }

            // 把消息发回客户端，告诉它登录成功了
            int ret = send(sID, &msg, sizeof(msg), 0);
            if (ret == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == AddDish)
        {
            char table_name[] = "Menu";
            MENU *pRgu = (MENU *)msg.buf;
            int ret = AddDish_sql(pRgu, table_name);
            if (1 == ret)
            {
                msg.type = ok;
            }
            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == DeleteDish)
        {
            char table_name[] = "Menu";
            MENU *pRgu = (MENU *)msg.buf;
            int ret = Delete_sql(pRgu, table_name);
            if (1 == ret)
            {
                msg.type = ok;
            }
            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == ModifyDish)
        {
            char table_name[] = "Menu";
            MENU *pRgu = (MENU *)msg.buf;
            int ret = Modify_sql(pRgu, table_name);
            if (1 == ret)
            {
                msg.type = ok;
            }
            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == ShowDish)
        {
            QUREY_RST pQR;
            COMMODITY com;
            char table_name[] = "Menu";
            MENU *pRgu = (MENU *)msg.buf;
            int ret = show_Sql(&pQR, pRgu, table_name);
            if (1 == ret)
            {
                msg.type = ok;
                memcpy(msg.buf, &pQR, sizeof(QUREY_RST)); // 发送元数据
            }

            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }

            // 逐条发送数据
            for (int i = 1; i <= pQR.row; i++)
            {
                if (pQR.col >= 3) // 确保至少有3列
                {
                    // 将数据填充到 COMMODITY 结构体中
                    strcpy(com.dishName, pQR.pzResult[i * pQR.col + 2]); // Dishname
                    com.price = atof(pQR.pzResult[i * pQR.col + 3]);     // Price 转换为 double
                    com.sales = atoi(pQR.pzResult[i * pQR.col + 4]);     // Sales 转换为 int

                    // 将 COMMODITY 结构体数据复制到 msg.buf 中
                    memcpy(msg.buf, &com, sizeof(COMMODITY));

                    // 发送数据
                    send(sID, &msg, sizeof(msg), 0);
                }
            }
        }
        else if (msg.type == CheckOrder)
        {
            char table_name[] = "PendingOrder";
            MENU pRgu;
            QUREY_RST pQR;
            char shoreName[50];
            strcpy(shoreName, msg.buf);
            int ret = findPending_Sql(&pQR, table_name, shoreName);
            if (1 == ret)
            {
                msg.type = ok;
                memcpy(msg.buf, &pQR, sizeof(QUREY_RST)); // 发送元数据
            }

            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }

            // 逐条发送数据
            for (int i = 1; i <= pQR.row; i++)
            {
                if (pQR.col >= 7) // 确保至少有7列
                {
                    // 将数据填充到 COMMODITY 结构体中
                    pRgu.orderID = atoi(pQR.pzResult[i * pQR.col]);
                    strcpy(pRgu.dishName, pQR.pzResult[i * pQR.col + 1]);      // Dishname
                    pRgu.Sales = atoi(pQR.pzResult[i * pQR.col + 2]);          // Sales 转换为 int
                    pRgu.Price = atof(pQR.pzResult[i * pQR.col + 3]);          // Price 转换为 double
                    strcpy(pRgu.ClientName, pQR.pzResult[i * pQR.col + 4]);    // Dishname
                    strcpy(pRgu.ClientPhone, pQR.pzResult[i * pQR.col + 5]);   // Dishname
                    strcpy(pRgu.ClientAddress, pQR.pzResult[i * pQR.col + 6]); // Dishname
                    strcpy(pRgu.Time, pQR.pzResult[i * pQR.col + 7]);          // Dishname
                    // 将 COMMODITY 结构体数据复制到 msg.buf 中
                    memcpy(msg.buf, &pRgu, sizeof(MENU));

                    // 发送数据
                    send(sID, &msg, sizeof(msg), 0);
                }
            }
        }
        else if (msg.type == DealOrder)
        {
            QUREY_RST pQR;
            char table_name[] = "PendingOrder";
            char table_name02[] = "ClientOrders";
            char dealingOrder[] = "商家已接单，订单正在处理";
            int orderID;
            char clientName[20];
            char shoreName[50];
            strcpy(shoreName, msg.buf);
            orderID = atoi(msg.buf);

            // if (-1 == FindClientName_Sql(table_name, orderID, clientName))
            // {
            //     printf("查找用户名字失败\n");
            // }
            // printf("%s", clientName);

            if (-1 == FindClientOrder_Sql(&pQR, table_name, orderID))
            {
                printf("查找订单信息失败\n");
            }

            if (-1 == InsertClientOrder_Sql(&pQR, table_name02, dealingOrder))
            {
                printf("插入订单信息失败\n");
            }

            int ret = deletePending_Sql(table_name, orderID);
            if (1 == ret)
            {
                msg.type = ok;
            }
            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }
        }

        else if (msg.type == OrderCompleted)
        {
            ORDER_INFOR oRD;
            QUREY_RST pQR;
            char table_name[] = "ClientOrders";
            char table_name02[] = "clientRegister";
            char dealingOrder[] = "订单已完成，骑手接单中";
            int orderID;
            orderID = atoi(msg.buf);

            if (-1 == UpdateClientOrder_Sql01(&pQR, table_name, orderID))
            {
                printf("订单更新失败1\n");
            }
            printf("%s\n", dealingOrder);
            if (-1 == UpdateClientOrder_Sql02(&pQR, &oRD, table_name, dealingOrder))
            {
                printf("订单更新失败2\n");
            }

            if (-1 == findClient_Sql02(&pQR, &oRD, table_name02))
            {
                printf("给骑手的订单信息失败！\n");
            }
            memcpy(msg.buf, &oRD, sizeof(oRD));
            if (-1 == send(Rider_Addr[0].fd, &msg, sizeof(msg), 0))
            {
                printf("发送给骑手订单失败\n");
            }
        }
        else if (msg.type == ViewOrderHistory)
        {
            QUREY_RST pQR;
            MENU pRgu;
            char table_name[] = "ClientOrders";

            int ret = FindClientOrder_Sql02(&pQR, table_name, msg.buf);
            if (1 == ret)
            {
                msg.type = ok;
                memcpy(msg.buf, &pQR, sizeof(QUREY_RST)); // 发送元数据
            }
            int ret_sent = send(sID, &msg, sizeof(msg), 0);
            if (ret_sent == -1)
            {
                printf("发送数据出错了\n");
            }

            // 逐条发送数据
            for (int i = 1; i <= pQR.row; i++)
            {
                if (pQR.col >= 7) // 确保至少有3列
                {
                    // 将数据填充到 COMMODITY 结构体中
                    pRgu.orderID = atoi(pQR.pzResult[i * pQR.col]);
                    strcpy(pRgu.ClientName, pQR.pzResult[i * pQR.col + 1]);
                    strcpy(pRgu.dishName, pQR.pzResult[i * pQR.col + 2]);
                    pRgu.Sales = atoi(pQR.pzResult[i * pQR.col + 3]);
                    pRgu.Price = atof(pQR.pzResult[i * pQR.col + 4]); // Price 转换为 double
                    strcpy(pRgu.OrderState, pQR.pzResult[i * pQR.col + 5]);
                    strcpy(pRgu.Time, pQR.pzResult[i * pQR.col + 6]);

                    // 将 COMMODITY 结构体数据复制到 msg.buf 中
                    memcpy(msg.buf, &pRgu, sizeof(MENU));

                    // 发送数据
                    send(sID, &msg, sizeof(msg), 0);
                }
            }
        }

        else if (msg.type == MerchantOpensChat)
        {
            for (int i = 0; i < merchant_count; i++)
            {
                if (0 == (strcmp(Merchant_Addr[i].name, msg.buf)))
                {
                    Merchant_Addr[i].bo = true;
                    break;
                }
            }
        }

        else if (msg.type == MerchantCloseChat)
        {
            for (int i = 0; i < merchant_count; i++)
            {
                if (0 == (strcmp(Merchant_Addr[i].name, msg.buf)))
                {
                    Merchant_Addr[i].bo = false;
                    break;
                }
            }
        }

        else if (msg.type == FindSelfChats)
        {
            QUREY_RST pQR;
            SINGLE_CHAT *sc = (SINGLE_CHAT *)msg.buf;
            char table_name[] = "ChatRecords";

            if (-1 == (FindSelfChats_Sql(&pQR, table_name, sc->selfName)))
            {
                printf("聊天记录查找失败\n");
            }

            memcpy(msg.buf, &pQR, sizeof(QUREY_RST));
            if(-1==send(sID, &msg, sizeof(msg), 0))
            {
                perror("发送数据失败!\n");
            }

            if (pQR.row > 0)
            {

                // 逐条发送数据
                for (int i = 1; i <= pQR.row; i++)
                {
                    if (pQR.col >= 3) // 确保至少有3列
                    {
                        strcpy(sc->destName, pQR.pzResult[i * pQR.col]);
                        strcpy(sc->text, pQR.pzResult[i * pQR.col + 1]);
                        strcpy(sc->time, pQR.pzResult[i * pQR.col + 2]);

                        memcpy(msg.buf, sc, sizeof(SINGLE_CHAT));
                        // 发送数据
                        send(sID, &msg, sizeof(msg), 0);
                    }
                }

                if (-1 == DeleteSelfChats_Sql(table_name, sc->selfName))
                {
                    printf("删除记录失败\n");
                }
            }
        }

        else if (msg.type == WithClientPrivateChat)
        {
            SINGLE_CHAT *sc = (SINGLE_CHAT *)msg.buf;
            char table_name[] = "ChatRecords";
            bool is_find = false;

            printf("1111\n");
            for (int i = 0; i < client_count; i++)
            {
                printf("22222\n");
                if (strcmp(sc->destName, Client_Addr[i].name) == 0)
                {
                    printf("aaaa\n");
                    if (true == Client_Addr[i].bo)
                    {
                        printf("bbbb\n");
                        int ret_sent = send(Client_Addr[i].fd, &msg, sizeof(msg), 0);
                        if (ret_sent == -1)
                        {
                            printf("发送数据出错了\n");
                            is_find = true;
                        }
                        is_find = true;
                        break;
                    }
                    else
                    {
                        if (-1 == (insertChatRecords_sql(sc, table_name)))
                        {
                            printf("聊天记录插入失败\n");
                        }
                        is_find = true;
                    }
                    
                }
            }
            printf("33333\n");
            if (!is_find)
            {
                printf("44444\n");
                if (-1 == (insertChatRecords_sql(sc, table_name)))
                {
                    printf("聊天记录插入失败\n");
                }
            }
        }
    }

    else if (msg.identity == rider)
    {
        if (msg.type == Register)
        {
            char table_name[] = "riderRegister";
            RGU *rgu = (RGU *)msg.buf;
            insert_sql(rgu, table_name);
        }
        else if (msg.type == Login)
        {
            char table_name[] = "riderRegister";
            RGU *pRgu = (RGU *)msg.buf;
            QUREY_RST pQR;

            querySql(&pQR, pRgu, table_name);

            // 如果结果的行数是>0的，说明数据库中有记录，那么登陆成功
            if (pQR.row > 0)
            {
                // 因为登录成功了，所以把消息类型改为ok，再发回去
                msg.type = ok;
                // 把登录成功的用户名和地址保存起来
                strcpy(Rider_Addr[rider_count].name, pRgu->name);
                Rider_Addr[rider_count].fd = sID; // 登录成功后记住用户的套接字
                rider_count++;
            }

            printf("消息类型为：%d\n", msg.type);
            // 把消息发回客户端，告诉它登录成功了
            int ret = send(sID, &msg, sizeof(msg), 0);
            if (ret == -1)
            {
                printf("发送数据出错了\n");
            }
        }
        else if (msg.type == receiveOrder)
        {
            char table_name[] = "ClientOrders";
            char dealingOrder[] = "骑手已接单";
            QUREY_RST pQR;
            ORDER_INFOR oRD;
            RGU *rgu = (RGU *)msg.buf;
            int orderID;
            orderID = atoi(msg.buf);

            if (-1 == UpdateClientOrder_Sql01(&pQR, table_name, orderID))
            {
                printf("订单更新失败1\n");
            }
            printf("%s\n", dealingOrder);
            if (-1 == UpdateClientOrder_Sql02(&pQR, &oRD, table_name, dealingOrder))
            {
                printf("订单更新失败2\n");
            }
        }

        else if (msg.type == DeliveryCompleted)
        {
            char table_name[] = "ClientOrders";
            char dealingOrder[] = "骑手送达完成";
            QUREY_RST pQR;
            ORDER_INFOR oRD;
            RGU *rgu = (RGU *)msg.buf;
            int orderID;
            orderID = atoi(msg.buf);

            if (-1 == UpdateClientOrder_Sql01(&pQR, table_name, orderID))
            {
                printf("订单更新失败1\n");
            }
            printf("%s\n", dealingOrder);
            if (-1 == UpdateClientOrder_Sql02(&pQR, &oRD, table_name, dealingOrder))
            {
                printf("订单更新失败2\n");
            }
        }
    }
}

int main(int argc, char *argv[])
{

    if (initDatabase() == -1)
    {
        return -1;
    }
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;   // IPV4的网络地址版本
    sin.sin_port = htons(9000); // 把9000号端口转为网络字节序并赋值给端口参数

    u_int32_t ip = 0;
    // 把字符串ip地址转为网络字节序ip
    inet_pton(AF_INET, "192.168.249.129", &ip);
    sin.sin_addr.s_addr = ip;

    // 创建一个tcp套接字，参数1指定地址族，参数2指定协议，SOCK_STREAM代表是TCP，SOCK_DGRAM代表UDP
    int sID = socket(AF_INET, SOCK_STREAM, 0);
    // 使端口号马上能被重新使用
    int opt = 1;
    if (setsockopt(sID, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
    {
        perror("设置套接字属性出错");
    }
    // 把套接字和地址绑定（手机+手机号）
    if (-1 == bind(sID, (struct sockaddr *)&sin, sizeof(sin)))
    {
        perror("绑定地址失败，请等待30秒或者换一个端口试试");
        return 0;
    }

    // 打开监听功能，监听绑定地址上的来访请求，5代表同时允许5个客户端排队连接
    listen(sID, MAX_EVENT);

    int epoll_id = epoll_create1(0);
    if (-1 == epoll_id)
    {
        perror("epoll_create1\n");
        close(sID);
        return -1;
    }

    struct epoll_event ev, events[MAX_EVENT];
    ev.events = EPOLLIN; // 感兴趣的事件为有数据可读
    ev.data.fd = sID;    // 感兴趣的套接字
    epoll_ctl(epoll_id, EPOLL_CTL_ADD, sID, &ev);

    while (1)
    {
        // count是当前一共有多少个套集字有可读事件
        // 例如如果当前epoll对象中只有一个套接字有可读事件，那么epoll_wait就会把这个套接字的结构体存入events数组中
        // 而且是按顺序存放的，第一个有事件的套机字结构体就是下标为0的元素
        int count = epoll_wait(epoll_id, events, MAX_EVENT, -1);

        if (count == -1)
        {
            perror("epoll_wait\n");
            close(sID);
            return -1;
        }

        for (size_t i = 0; i < count; i++)
        {
            int fd = events[i].data.fd;
            printf("fd = %d\n", fd);
            if (fd == sID) // 说明i是监听套接字
            {
                printf("因为i(%lu)就是监听套接字，它上面发生的可读事件是说明有用户来连接我们了\n", i);
                struct sockaddr_in AllAddr;
                struct sockaddr_in ClientAddr;
                socklen_t len = sizeof(struct sockaddr_in);
                int newFd = accept(fd, (struct sockaddr *)&AllAddr, &len);
                printf("产生了一个新的套接字，快为它准一个结构体，并加入到epoll对象中管理起来吧\n");
                ev.data.fd = newFd; // 把新的套接字赋值给结构体
                // epoll操作和控制，EPOLL_CTL_ADD是往epoll对象中添加结构体
                if (0 != epoll_ctl(epoll_id, EPOLL_CTL_ADD, newFd, &ev))
                {
                    perror("epoll_ctl\n");
                    close(newFd);
                    continue;
                }
                else
                    printf("加入套接字成功\n");
            }
            else
            {
                MSG msg;
                int ret = read(fd, &msg, sizeof(MSG));
                if (ret <= 0)
                {
                    // 把要移除的套接字结构体准备好
                    ev.data.fd = fd;
                    // 把套接字结构体从epoll中移除掉
                    if (0 == epoll_ctl(epoll_id, EPOLL_CTL_DEL, fd, &ev))
                    {
                        printf("从epoll中移除套接字结构体成功\n");
                    }
                    else
                    {
                        perror("epoll");
                        printf("从epoll中移除套接字结构体失败\n");
                    }
                    close(fd);
                    continue; // 指向下一个循环
                }
                else
                {
                    /*
                    // 第一次接收到某个端用户的请求，分别存储到不同端在线的数组中，这就相当于报道
                    if (msg.identity == client && -1 == msg.type)
                    {
                        Client_Addr[client_count++] = fd;
                    }
                    else if (msg.type == merchant && -1 == msg.type)
                    {
                        Merchant_Addr[merchant_count++] = fd;
                    }
                    else if (msg.type == rider && -1 == msg.type)
                    {
                        Rider_Addr[rider_count++] = fd;
                    }
                    // 如果某个端有请求需要服务端处理
                    else*/
                    work(fd, msg);
                }
            }
        }
    }
    close(sID);

    return 0;
}